package com.xbongbong.saas.service;

import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.PaymentSheetTypeEnum;
import com.xbongbong.paas.enums.SheetTypeEnum;
import com.xbongbong.paas.pojo.FieldAttrEntityForImport;
import com.xbongbong.paas.pojo.dto.AddBatchDTO;
import com.xbongbong.paas.pojo.dto.FormDataAddDTO;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.dto.ImportFormDataDTO;
import com.xbongbong.paas.pojo.dto.SaasFormSaveDTO;
import com.xbongbong.paas.pojo.dto.ValidateDataDTO;
import com.xbongbong.paas.pojo.imports.CellTitlePojo;
import com.xbongbong.paas.pojo.imports.RowGroupPojo;
import com.xbongbong.paas.pojo.vo.FormDataAddVO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.pro.applist.pojo.vo.ListAppVO;
import com.xbongbong.pro.businessdata.pojo.dto.FormatExplainDTO;
import com.xbongbong.pro.formdata.pojo.AfterSavePojo;
import com.xbongbong.pro.formdata.pojo.SaasNeedRedundantAttrPojo;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainInLinkItemDTO;
import com.xbongbong.pro.listbatch.pojo.dto.AddLabelDTO;
import com.xbongbong.pro.paymentsheet.pojo.dto.PaymentSheetDeleteBatchDTO;
import com.xbongbong.pro.paymentsheet.pojo.dto.PaymentSheetEditAttrUpdateDTO;
import com.xbongbong.pro.paymentsheet.pojo.dto.PaymentSheetGetDTO;
import com.xbongbong.pro.paymentsheet.pojo.dto.PaymentSheetSaveDTO;
import com.xbongbong.pro.paymentsheet.pojo.dto.PaymentSheetUpdateBatchDTO;
import com.xbongbong.pro.paymentsheet.pojo.dto.batch.PaymentSheetDTO;
import com.xbongbong.pro.paymentsheet.pojo.vo.PaymentSheetDeleteBatchVO;
import com.xbongbong.pro.paymentsheet.pojo.vo.PaymentSheetGetVO;
import com.xbongbong.pro.paymentsheet.pojo.vo.PaymentSheetUpdateBatchVO;
import com.xbongbong.pro.paymentsheet.pojo.vo.batch.PaymentSheetAmountVO;
import com.xbongbong.pro.sheet.pojo.AmountDetailGetPojo;
import com.xbongbong.saas.domain.entity.ext.PaymentSheetEntityExt;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;

import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * 回款单
 *
 * @author 吴峰
 * @version v1.0
 * @date 2019/2/23
 * @since v1.0
 */
public interface PaymentSheetService {

    /**
     * 批量删除回款单
     * @param paymentSheetDeleteBatchDTO
     * @param delEnum
     * @return
     * @throws XbbException
     * @update 增加delEnum参数，用于控制审批拒绝的回退，此时传入 DelEnum.INVALID
     */
    PaymentSheetDeleteBatchVO deleteBatch(PaymentSheetDeleteBatchDTO paymentSheetDeleteBatchDTO, DelEnum delEnum) throws XbbException;

    /**
     * 新建时格式化解释
     *
     * @param formatExplainDTO 入参
     * @throws XbbException 异常
     */
    void formatAddExplain(FormatExplainDTO formatExplainDTO) throws XbbException;

    /**
     * 关联新建红冲预收款余额回款单
     *
     * @param handlerExplainInLinkItemDTO 入参
     * @return 解释
     * @throws XbbException 异常
     */
    void formatLinkAddRedPrepayment(HandlerExplainInLinkItemDTO handlerExplainInLinkItemDTO) throws XbbException;

    /**
     * 关联新建核销预收款
     * @param handlerExplainInLinkItemDTO 入参
     * @throws XbbException error
     */
    void formatLinkAddWriteOffPrepayment(HandlerExplainInLinkItemDTO handlerExplainInLinkItemDTO) throws XbbException;

    /**
     * 保存
     *
     * @param paymentSheetSaveDTO 入参
     * @return 返回数据id
     * @throws XbbException 异常
     */
    FormDataAddVO add(PaymentSheetSaveDTO paymentSheetSaveDTO, PaasFormDataEntity paasFormDataEntity, PaasFormEntityExt paasFormEntityExt) throws XbbException;

    /**
     * 获取回款单
     *
     * @param paymentSheetSaveDTO 入参
     * @return 回参
     * @throws XbbException 异常
     */
    PaymentSheetGetVO get(PaymentSheetGetDTO paymentSheetSaveDTO) throws XbbException;

    /**
     * 已核销、预收款核销保存
     * 预收款核销需要处理预收款的余额，且预收款核销的【回款金额】需置为空
     * @param paymentSheetTypeEnum 回款类型
     * @param paymentSheetSaveDTO 保存dto
     * @param paasFormDataEntity 数据实体
     * @param paasFormEntityExt 表单form
     * @throws  XbbException
     * @author 伟强
     * @date 19/11/15 025 15:07
     * @update 19/11/25 025 15:07 by zcp 优化关联应收款、合同的更新，融合已核销、预收款核销同时使用该方法
     * @since v1.0
     * @version v1.0
     */
    void writeOffSave(PaymentSheetTypeEnum paymentSheetTypeEnum, PaymentSheetSaveDTO paymentSheetSaveDTO, PaasFormDataEntity paasFormDataEntity, PaasFormEntityExt paasFormEntityExt) throws XbbException;

    /**
     * 红冲已核销、红冲预收款核销、红冲预收款核销(退到余额)
     * @param sheetTypeEnum
     * @param paymentSheetSaveDTO
     * @param paasFormDataEntity
     * @param paasFormEntityExt
     * @throws XbbException
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    void redSave(SheetTypeEnum sheetTypeEnum, PaymentSheetSaveDTO paymentSheetSaveDTO, PaasFormDataEntity paasFormDataEntity, PaasFormEntityExt paasFormEntityExt) throws XbbException;

    /**
     * 坏账回款单
     * @param paymentSheetSaveDTO
     * @param paasFormDataEntity
     * @param paasFormEntityExt
     * @throws XbbException
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    void badSave(PaymentSheetSaveDTO paymentSheetSaveDTO, PaasFormDataEntity paasFormDataEntity, PaasFormEntityExt paasFormEntityExt) throws XbbException;

    /**
     * 预收款、红冲预收款余额回款单保存
     * @param sheetTypeEnum 回款单类型
     * @param paymentSheetSaveDTO 入参
     * @param paasFormDataEntity data实体
     * @param paasFormEntityExt form
     * @throws XbbException error
     * @author zhouwq
     * @date 2019/11/21 14:09
     * @update 2019/12/16 by zcp 预收款、红冲预收款合并为一个方法
     */
    void prepaymentSave(SheetTypeEnum sheetTypeEnum, PaymentSheetSaveDTO paymentSheetSaveDTO, PaasFormDataEntity paasFormDataEntity, PaasFormEntityExt paasFormEntityExt) throws XbbException;



    /**
     * 获取应收款下的回款单
     *
     * @param corpid        公司id
     * @param paymentId     付款计划id
     * @author GuoJun.HU
     * @since V1.0
     * @return
     * @date 2019/4/11 14:17
     */
    List<PaasFormDataEntityExt> getPaymentSheetEsDataListByPaymentId(String corpid, Long paymentId) throws XbbException;
    
    /**
     * 批量获取用户下的红冲预收款和预收款回款单
     * @param corpid
     * @param customerIds
     * @param typeList
     * @return
     * @throws XbbException
     */
    List<PaasFormDataEntityExt> getPaymentSheetEsDataListByCustomerIds(String corpid, List<Long> customerIds, List<String> typeList) throws XbbException;
    /**
     * 获取客户下的回款单
     *
     * @param corpid        公司id
     * @param customerId     付款计划id
     * @author GuoJun.HU
     * @since V1.0
     * @return
     * @date 2019/4/11 14:17
     */
    List<PaasFormDataEntityExt> getPaymentSheetEsDataListByCustomerId(String corpid, Long customerId, List<String> codeList, UserVO loginUser) throws XbbException;

    /**
     * 回款单前置处理：
     * （1）把关联客户、关联合同、关联应收款、关联原始回款单处理成可以保存的格式
     * （2）把回款单类型置入data内（注：审批内7种类型回款单都是统一为702，其类型已经在data内，所以置入类型时需要判断data内是否已经存在类型）
     * @param validateDataDTO
     * @throws XbbException
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    void beforeSave(ValidateDataDTO validateDataDTO) throws XbbException;

    /**
     * 回款单保存后逻辑
     * @param saasFormSaveDTO saas保存数据
     * @throws XbbException 业务异常
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    void afterSave(SaasFormSaveDTO saasFormSaveDTO) throws XbbException;

    /**
     * 更新回滚es - 查数据库数据同步至es
     * @param idIn
     * @param corpid
     * @throws XbbException
     */
    void updateRollback(Collection<Long> idIn, String corpid) throws XbbException;

    /**
     * 格式化移动端列表页
     *
     * @param formDataListDTO 入参
     * @param esEntities 数据列表
     * @param totalCount 数据个数
     * @return com.xbongbong.pro.applist.pojo.vo.ListAppVO
     * @throws XbbException 异常
     * @author 徐俊杰
     * @date 2019/11/20 9:29
     * @since v1.0
     */
    ListAppVO formatPaymentSheetAppList(FormDataListDTO formDataListDTO, List<PaasFormDataEntityExt> esEntities, Integer totalCount) throws XbbException;

    /**
     * 批量更新-只更新特定字段
     * @param paymentSheetUpdateBatchDTO
     * @return com.xbongbong.pro.paymentsheet.pojo.vo.PaymentSheetUpdateBatchVO
     * @throws XbbException
     * @author zcp
     * @date 19/11/25 025 19:25
     * @update 19/11/25 025 19:25
     * @since v1.0
     * @version v1.0
     */
    PaymentSheetUpdateBatchVO updateAttrBatch(PaymentSheetUpdateBatchDTO paymentSheetUpdateBatchDTO) throws XbbException;
    PaymentSheetUpdateBatchVO updateAttrBatch(PaymentSheetUpdateBatchDTO paymentSheetUpdateBatchDTO, boolean needThrow) throws XbbException;

    /**
     * 列表页批量编辑
     * @param paymentSheetEditAttrUpdateDTO
     * @return com.xbongbong.paas.toolbox.wrap.BaseVO
     * @throws XbbException
     * @author zcp
     * @date 19/11/25 025 19:10
     * @update 19/11/25 025 19:10
     * @since v1.0
     * @version v1.0
     */
    void batchEditAttr(PaymentSheetEditAttrUpdateDTO paymentSheetEditAttrUpdateDTO) throws XbbException;
    
    /**
     * 批量保存前置
     * @return
     * @throws XbbException
     * @param formDataSaveDTO
     * @param paymentSheetTypeEnum 回款单类型
     * @param customerId
     * @author
     */
    AddBatchDTO beforeSaveBatch(FormDataAddDTO formDataSaveDTO, PaymentSheetTypeEnum paymentSheetTypeEnum, Long customerId) throws XbbException;
    
    /**
     * 批量保存回款单
     * @param paymentSheetDTO
     * @param paymentSheetTypeEnum
     * @param customerId
     * @return
     * @throws XbbException
     */
    PaymentSheetAmountVO addBatch(PaymentSheetDTO paymentSheetDTO, PaymentSheetTypeEnum paymentSheetTypeEnum, Long customerId) throws XbbException;

    /**
     * Description: 批量保存回款单(工作流)
     * @param paymentSheetDTO
	 * @param paymentSheetTypeEnum
	 * @param customerId
     * @return com.xbongbong.pro.paymentsheet.pojo.vo.batch.PaymentSheetAmountVO
     * @throws
     * @author 魏荣杰
     * @date 2021/9/22 15:31
     * @since
     */
    PaymentSheetAmountVO addBatchForWorkflow(PaymentSheetDTO paymentSheetDTO, PaymentSheetTypeEnum paymentSheetTypeEnum, Long customerId) throws XbbException;

    /**
     * 根据关联数据id判断是否存在关联数据
     * @param corpid
     * @param linkIds
     * @param attr
     * @return
     * @throws XbbException
     */
    Map<Long, PaasFormDataEntityExt> getEsDataMapByLinkIds(String corpid, List<Object> linkIds, PaymentSheetEnum attr) throws XbbException;

    /**
     * 得到原单的已红冲总金额，并查询原单关联的已红冲单据封装成contractId_paymentId 和 红冲金额的对应关系map（如果有子单则得到子单的对应关系）
     * 注：此方法未对红冲金额求正值，因此此时的红冲金额还为负数
     * @param corpid 公司id
     * @param sheetId 原单id
     * @param amountDetailGetPojo 获取金额明细时需要用到的条件、原单信息pojo
     * @return java.util.Map<java.lang.String,java.lang.Double>
     * @throws XbbException
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    Map<String, Double> handleRedSheetsBySheet(String corpid, Long sheetId, AmountDetailGetPojo amountDetailGetPojo) throws XbbException;

    /**
     * 计算回款单已经红冲的总金额，即求和关联原始回款单id为sheetId的回款单的红冲金额
     * 注：此方法未对红冲金额求正值，因此此时的红冲金额还为负数
     * @param corpid 公司id
     * @param sheetId 回款单id
     * @return double
     * @throws XbbException
     * @author zcp
     * @date 19/12/8 008 16:38
     * @update 19/12/8 008 16:38
     * @since v1.0
     * @version v1.0
     */
    double sumRedAmountBySheet(String corpid, Long sheetId) throws XbbException;
    
    /**
     * 统计该类型的金额
     * @param corpid
     * @param sheetId
     * @param codeList
     * @return
     * @throws XbbException
     */
    double sumAmountBySheet(String corpid, Long sheetId, List<String> codeList) throws XbbException;
    /**
     * 计算回款单已红冲的总金额
     * @param corpid 公司ID
     * @param sheetIdIn 原回款单ID集合
     * @return 回款单ID和已红冲金额关系map
     * @throws XbbException error
     * @author zhouwq
     * @date 2019/12/18 14:00
     */
    Map<Long, Double> sumRedAmountByPaymentSheetIdIn(String corpid, List<Long> sheetIdIn) throws XbbException;

    /**
     * 将Excel数据格式化成表单保存需要的JSON格式的数据
     *
     * @param importFormDataDTO 导入入参
     * @param titlePojoList     标题
     * @param rowGroupPojo      一个表单对应的一组Excel填写的数据
     * @param fieldAttrList     解释
     * @return com.xbongbong.paas.pojo.dto.FormDataAddDTO
     * @throws XbbException
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    FormDataAddDTO formatExcelValue(ImportFormDataDTO importFormDataDTO, List<CellTitlePojo> titlePojoList, RowGroupPojo rowGroupPojo, List<FieldAttrEntityForImport> fieldAttrList) throws XbbException;

    /**
     * Description: 一致性同步
     * @param corpid 公司ID
     * @param customerId 客户ID
     * @param customerName 客户名称
     * @author zhouwq
     * @date 2020/3/5 8:48
     * @throws XbbException error
     */
    void dataConsistencyUpdateCustomer(String corpid, Long customerId, String customerName) throws XbbException;

    /**
     * 一致性同步
     * @param corpid 公司ID
     * @param contractId 合同id
     * @param serialNo 合同编号
     * @throws XbbException
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    void dataConsistencyUpdateContract(String corpid, Long contractId, String serialNo) throws XbbException;
    /**
     * 批量增删标签
     * @param addLabelDTO
     * @param addBatchList
     * @throws XbbException
     */
    void updateBatchLabelAttr(AddLabelDTO addLabelDTO, List<PaasFormDataEntityExt> addBatchList, Boolean addOrDelete) throws XbbException;

    /**
     * 工作流回款单团队保存
     *
     * @param saasFormSaveDTO
     */
    void afterSaveForWorkflow(SaasFormSaveDTO saasFormSaveDTO) throws XbbException;

    /**
     * 操作回款单团队
     *
     * @param paymentSheetEntityExt
     * @param sheetList
     * @param ignoreMainSheet
     * @param paasFormDataEntity
     * @param saasNeedRedundantAttrPojo
     * @param isImport
     * @throws XbbException
     */
    AfterSavePojo operateSheetTeam(PaymentSheetEntityExt paymentSheetEntityExt, List<PaymentSheetEntityExt> sheetList,
                                   boolean ignoreMainSheet, PaasFormDataEntity paasFormDataEntity, SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo, Integer isImport, Boolean workFlowTag) throws XbbException;

    void afterSaveForUpdateWorkflow(SaasFormSaveDTO saasFormSaveDTO) throws XbbException;
}
